home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / prospero / propsero.lha / prospero-beta.4.2e / user / newvs.c < prev    next >
C/C++ Source or Header  |  1992-02-10  |  16KB  |  609 lines

  1. /*
  2.  * Copyright (c) 1989, 1990, 1991 by the University of Washington
  3.  * Copyright (c) 1991, 1992 by the University of Southern California
  4.  *
  5.  * For copying and distribution information, please see the files
  6.  * <uw-copyright.h> and <usc-copyr.h>.
  7.  */
  8.  
  9. #include <uw-copyright.h>
  10. #include <usc-copyr.h>
  11. #include <psite.h>
  12.  
  13. #define VERBOSE
  14.  
  15. /*
  16.  * newvs - Create new virtual systems
  17.  *
  18.  * Verbosity flag:  0 - Prompt for input
  19.  *                  1 - Explain what is needed as input
  20.  *                  2 - List each action taken
  21.  *                  3 - Stop before each step
  22.  *                  4 - Stop before each step, and explain the action
  23.  */
  24.  
  25. /* make more efficinet by caching some of the dir pointers */
  26.  
  27. #include <stdio.h>
  28. #include <strings.h>
  29.  
  30. #include <pfs.h>
  31. #include <perrno.h>
  32.  
  33. #define max(x,y)  (((x) > (y)) ? x : y)
  34.  
  35. int    perrno;
  36. int    pfs_debug = 0;
  37.  
  38. main(argc,argv)
  39.     int        argc;
  40.     char    *argv[];
  41.     {
  42.     char        *progname = argv[0];
  43.     char        *cur_arg;
  44.  
  45.     char        vshost[100];
  46.     char        vsname[100];
  47.     char        home[100];
  48.     char        vsdescfile[100];
  49.     char        owner[100];
  50.  
  51.     FILE        *vsdesc;
  52.  
  53.     char        vsnamepath[100];
  54.     char        vsabsname[100];
  55.  
  56.     char        vs_root[MAX_VPATH];
  57.     char        vs_subdir[MAX_VPATH];
  58.     char        vs_temp[MAX_VPATH];
  59.  
  60.     char        cont[100];
  61.  
  62.     VDIR_ST        dir_st;         
  63.     VDIR        dir= &dir_st;
  64.     VLINK        pl;         /* Prototype links */
  65.     VLINK        vl;
  66.  
  67.     ACL_ST    oacl_st;        /* Owner ACL */
  68.     ACL    oacl = &oacl_st;    /* Owner ACL pointer */
  69.  
  70.     int        empty = 0;
  71.  
  72. #ifdef VERBOSE
  73.     int        verbose = 2;
  74. #endif VERBOSE
  75.  
  76.     char        *period;
  77.     int        nchr;
  78.     int        retval;
  79.  
  80.     vdir_init(dir);
  81.  
  82.     *vshost = '\0';
  83.     *vsname = '\0';
  84.     *home = '\0';
  85.     *owner = '\0';
  86.     *vsdescfile = '\0';
  87.  
  88.     argc--;argv++;
  89.  
  90.     while (argc > 0 && **argv == '-') {
  91.         cur_arg = argv[0]+1;
  92.  
  93.         /* If a - by itself, then no more arguments */
  94.         if(!*cur_arg) {
  95.         argc--, argv++;
  96.         goto scandone;
  97.         }
  98.  
  99.         while (*cur_arg) {
  100.         switch (*cur_arg++) {
  101.         
  102.         case 'D':  /* Debug level */
  103.             pfs_debug = 1; /* Default debug level */
  104.             sscanf(cur_arg,"%d",&pfs_debug);
  105.             cur_arg += strspn(cur_arg,"0123456789");
  106.             break;
  107.  
  108.         case 'e': /* Empty */
  109.             empty++;
  110.             break;
  111.  
  112. #ifdef VERBOSE
  113.         case 'v':  /* Verbosity */
  114.         case 'V':  /* Verbosity */
  115.             verbose = 1; /* Default debug level */
  116.             sscanf(cur_arg,"%d",&verbose);
  117.             cur_arg += strspn(cur_arg,"0123456789");
  118.             break;
  119. #endif VERBOSE
  120.  
  121.         default:
  122.             fprintf(stderr,
  123.                 "Usage: newvs [host [name [home [owner [descfile]]]]]\n");
  124.             exit(1);
  125.         }
  126.         }
  127.         argc--, argv++;
  128.     }
  129.     scandone:
  130.  
  131.     if (argc > 5)  {
  132.         fprintf(stderr,
  133.             "Usage: newvs [host [name [home [owner [descfile]]]]]\n");
  134.         exit(1);
  135.     }
  136.  
  137.     /* check for args in order host, vsname, homedir */
  138.     /* If still some left, print error message */
  139.     if (argc > 0) strcpy(vshost,argv[1]);
  140.     if (argc > 1) strcpy(vsname,argv[2]);
  141.     if (argc > 2) strcpy(home,argv[3]);
  142.     if (argc > 3) strcpy(owner,argv[4]);
  143.     if (argc > 4) strcpy(vsdescfile,argv[5]);
  144.  
  145. #ifdef VERBOSE
  146.     if(verbose >= 2) printf("\nSetting virtual system to %s...",P_MASTER_VS);
  147. #endif VERBOSE
  148.  
  149.     sprintf(vs_temp,"/VIRTUAL-SYSTEMS/%s",P_MASTER_VS);
  150.     if(pget_wdhost()) vfsetenv("","",vs_temp);
  151.     else vfsetenv("","",P_MASTER_VS);
  152.  
  153. #ifdef VERBOSE
  154.     if(verbose >= 2) printf("Done.\n");
  155.  
  156.     if(verbose >= 2) printf("Reading list of storage sites from /pfs_storage...");
  157. #endif VERBOSE
  158.  
  159.     retval = rd_vdir("/pfs_storage",0,dir,0);
  160.  
  161.     if(retval) {
  162.         perrmesg("Can't read /pfs_storage: ", retval, NULL);
  163.         exit(1);
  164.     }
  165.  
  166. #ifdef VERBOSE
  167.     if(verbose >= 2) printf("Done.\n");
  168.  
  169.     if((verbose >= 1) && (*vshost == '\0')) {
  170.         printf("\nHost is the name of the host on which the root\n");
  171.         printf("of the new virtual system is to be stored.  For a\n");
  172.         printf("list of choices type a question mark.\n\n");
  173.     }
  174. #endif VERBOSE
  175.  
  176.     prompthost:
  177.     if(*vshost == '\0') {
  178.         printf("Host: ");
  179.         gets(vshost);
  180.     }
  181.     
  182.     if((*vshost == '\0') || (strcmp(vshost,"?") == 0)) {
  183.         vl = dir->links;
  184.  
  185.         printf("\n");
  186.         while(vl) {
  187.         printf(" %s\n",vl->name);
  188.         vl = vl->next;
  189.         }
  190.         printf("\n");
  191.         *vshost = '\0';
  192.         goto prompthost;
  193.     }
  194.  
  195.     vl = dir->links;
  196.  
  197.     while(vl) {
  198.         nchr = 0; period = index(vl->name,'.');
  199.         if(period) nchr = period - vl->name;
  200.         nchr = max(strlen(vshost), nchr);
  201.  
  202.         if(strcncmp(vl->name,vshost,nchr) == 0) break;
  203.         vl = vl->next;
  204.     }
  205.  
  206.     if(vl == NULL) {
  207.         printf("Not found.\n");
  208.         *vshost = '\0';
  209.         goto prompthost;
  210.     }
  211.  
  212.     sprintf(vs_root,"/pfs_storage/%s/local_vsystems/",vl->name);
  213.  
  214. #ifdef VERBOSE
  215.     if((verbose >= 1) && (*vsname == '\0')) {
  216.         printf("\nName is the default name by which others will refer\n");
  217.         printf("to the new virtual system.  If this is your personal\n");
  218.         printf("virtual system, it should be your username.  If this\n");
  219.         printf("virtual system is for a project, a name describing the\n");
  220.         printf("project is appropriate.  Additional names may be\n");
  221.         printf("added at a later time.\n\n");
  222.     }
  223. #endif VERBOSE
  224.  
  225.     promptvsname:
  226.     if(*vsname == '\0') {
  227.         printf("Name: ");
  228.         gets(vsname);
  229.     }
  230.     
  231.     if(*vsname == '\0') goto promptvsname;
  232.  
  233.     sprintf(vsnamepath,"/%s/VIRTUAL-SYSTEMS/%s",P_PROTOTYPE_VS,vsname);
  234.  
  235.     retval = rd_vdir(vsnamepath,0,dir,RVD_DFILE_ONLY);
  236.  
  237.     if((retval == 0) && dir->links) {
  238. #ifdef VERBOSE       
  239.         if(verbose >= 1) {
  240.         printf("\nThe name you have chosen is already in use.\n");
  241.         printf("This means that the name is already being used\n");
  242.         printf("by local users to refer to a different virtual\n");
  243.         printf("system.  Please choose a different name.  You\n");
  244.         printf("may add an additional name at a later time, \n");
  245.         printf("including one that is already in use.\n\n");
  246.         }
  247.         else 
  248. #endif VERBOSE
  249.         printf("Name already in use, please choose another.\n");
  250.  
  251.         *vsname = '\0';
  252.         goto promptvsname;
  253.     }
  254.  
  255.     strcat(vs_root,vsname);
  256.  
  257. #ifdef VERBOSE
  258.     if((verbose >= 1) && (*home == '\0')) {
  259.         printf("\nHome is the name of the home directory relative\n");
  260.         printf("to the root of the new virtual system.  If this is\n");
  261.         printf("a personal virtual system, \"/vsname\" where vsname is\n");
  262.         printf("the name of the virtual system is suggested.  If the\n");
  263.         printf("directory is top level and does not already exist,\n");
  264.         printf("then it will be automatically created.\n\n");
  265.     }
  266. #endif VERBOSE
  267.  
  268.     prompthome:
  269.     if(*home == '\0') {
  270.         printf("Home Directory: ");
  271.         gets(home);
  272.     }
  273.     
  274.     if(*home == '\0') goto prompthome;
  275.  
  276.     /* Need better checking for valid names */
  277.     if(*home != '/') {
  278.         printf("Path must begin with a /.\n");
  279.         *home = '\0';
  280.         goto prompthome;
  281.     }
  282.  
  283. #ifdef VERBOSE
  284.     if((verbose >= 1) && (*owner == '\0')) {
  285.         printf("\nOwner is a list of users authorized to change\n");
  286.         printf("the new virtual system.  The owner will be granted\n");
  287.         printf("full rights in the directories that are created.\n\n");
  288.     }
  289. #endif VERBOSE
  290.  
  291.     promptowner:
  292.     if(*owner == '\0') {
  293.         printf("Owner: ");
  294.         gets(owner);
  295.     }
  296.     
  297.     if(*owner == '\0') goto promptowner;
  298.  
  299.     /* Start constructing systems */
  300.  
  301. #ifdef VERBOSE
  302.     if(verbose == 3) 
  303.         printf("\nAbout to create root of virtual system.\n[Type <CR> to continue]");
  304.  
  305.     if(verbose >= 4) {
  306.         printf("\nAbout to create the root of the virtual system.\n");
  307.         printf("This is accomplished by creating the directory:\n\n");
  308.         printf("    %s\n\n",vs_root);
  309.         printf("relative to the root of the master virtual system.\n");
  310.         printf("[Type <CR> to continue]");
  311.     }
  312.  
  313.     if(verbose >= 3) {
  314.         gets(cont);
  315.         printf("\n");
  316.     }
  317.  
  318.     if(verbose >= 2) 
  319.         printf("Creating %s...",vs_root);
  320. #endif VERBOSE
  321.  
  322.     retval = mk_vdir(vs_root,MKVD_LPRIV);
  323.     if(retval == DIRSRV_NOT_AUTHORIZED) {
  324.         fflush(stdout);
  325.         perrmesg("\nUnable to create virtual system: ", retval, NULL);
  326.         exit(1);
  327.     }
  328.     if(retval && (retval != DIRSRV_ALREADY_EXISTS)) {
  329.         perrmesg("Error creating root: ", retval, NULL);
  330.         exit(1);
  331.     }
  332.  
  333. #ifdef VERBOSE
  334.     if(verbose >= 2) printf("Done.\n");
  335.     if(verbose >= 2) printf("Setting ACL...");
  336. #endif VERBOSE
  337.  
  338.     retval = rd_vdir(vs_root,0,dir,RVD_DFILE_ONLY);
  339.  
  340.     oacl->acetype = ACL_ASRTHOST;
  341.     oacl->atype = "";
  342.     oacl->rights = "ALRMDI";
  343.     oacl->principals = owner;
  344.     if(!retval) 
  345.         retval = modify_acl(dir->links,NULL,oacl,MACL_DIRECTORY|MACL_ADD);
  346.  
  347.     if(retval) {
  348.         perrmesg("Error setting ACL: ", retval, NULL);
  349.         exit(1);
  350.     }
  351.  
  352. #ifdef VERBOSE
  353.     if(verbose >= 2) printf("Done.\n");
  354.     if(verbose >= 2) printf("Reading /%s...",P_PROTOTYPE_VS);
  355. #endif VERBOSE
  356.     sprintf(vs_temp,"/%s",P_PROTOTYPE_VS);
  357.     retval = rd_vdir(vs_temp,0,dir,RVD_EXPAND);
  358.     if(retval) {
  359.         perrmesg("Error reading prototype: ", retval, NULL);
  360.         exit(1);
  361.     }
  362.  
  363. #ifdef VERBOSE
  364.     if(verbose >= 2) printf("Done.\n\n");
  365. #endif VERBOSE
  366.  
  367.     if(empty) goto leave_empty;
  368.  
  369. #ifdef VERBOSE
  370.     if(verbose == 3) printf("About to setup subdirectories.\n[Type <CR> to continue]");
  371.  
  372.     if(verbose >= 4) {
  373.         printf("About to setup subdirectories.  For each subdirectory in\n");
  374.         printf("/%s, a new subdirectory will be created in the new\n",P_PROTOTYPE_VS);
  375.         printf("virtual system.  The subdirectory from /%s will\n",P_PROTOTYPE_VS);
  376.         printf("then be added as a union link.  This creates a customizable\n");
  377.         printf("subdirectory whose contents track that of the master copy.\n");
  378.         printf("[Type <CR> to continue]");
  379.     }
  380.  
  381.     if(verbose >= 3) {
  382.         gets(cont);
  383.         printf("\n");
  384.     }
  385. #endif VERBOSE
  386.  
  387.     pl = dir->links;
  388.  
  389.     while(pl) {
  390.         if(strcmp(pl->name,"VS-DESCRIPTION") != 0) {
  391.         sprintf(vs_subdir,"%s/%s",vs_root,pl->name);
  392. #ifdef VERBOSE
  393.         if(verbose >= 2) printf("Creating %s...",vs_subdir);
  394. #endif VERBOSE
  395.         retval = mk_vdir(vs_subdir,MKVD_LPRIV);
  396.         if(retval && (retval != DIRSRV_ALREADY_EXISTS)) {
  397.             perrmesg("Error creating subdir: ", retval, NULL);
  398.             exit(1);
  399.         }
  400.  
  401. #ifdef VERBOSE
  402.         if(verbose >= 2) printf("Adding union link to master copy...");
  403. #endif VERBOSE
  404.         retval = add_vlink(vs_subdir,"master",pl,AVL_UNION);
  405.         if(retval && (retval != DIRSRV_ALREADY_EXISTS)) {
  406.             perrmesg("Error adding union link: ", retval, NULL);
  407.             exit(1);
  408.         } 
  409. #ifdef VERBOSE
  410.         if(verbose >= 2) printf("Done.\n");
  411. #endif VERBOSE
  412.         }
  413.         pl = pl->next;
  414.     }
  415.  
  416.     leave_empty:
  417.  
  418.     if(strcmp(home,"/") == 0) goto no_home;
  419.  
  420.     sprintf(vs_subdir,"%s%s",vs_root,home);
  421.  
  422. #ifdef VERBOSE
  423.     if(verbose >= 3) printf("\nAbout to create home directory.\n[Type <CR> to continue]");
  424.  
  425.     if(verbose >= 3) {
  426.         gets(cont);
  427.         printf("\n");
  428.     }
  429.  
  430.     if(verbose >= 2) printf("Creating %s...",vs_subdir);
  431. #endif VERBOSE
  432.  
  433.     retval = mk_vdir(vs_subdir,MKVD_LPRIV);
  434.     if(retval) perrmesg("Home directory not created: ", retval, NULL);
  435.  
  436. #ifdef VERBOSE
  437.     if(verbose >= 2) printf("Done.\n",vs_subdir);
  438. #endif VERBOSE
  439.  
  440.     no_home:
  441.  
  442. #ifdef VERBOSE
  443.     if(verbose == 3) printf("\nAbout to create VS-DESCRIPTION.\n[Type <CR> to continue]");
  444.  
  445.     if(verbose >= 4) {
  446.         printf("\nAbout to create VS-DESCRIPTION.  This will contain information\n");
  447.         printf("about the root and home directory of the virtual system.\n");
  448.         printf("[Type <CR> to continue]");
  449.     }
  450.  
  451.     if(verbose >= 3) {
  452.         gets(cont);
  453.         printf("\n");
  454.     }
  455.  
  456.     if(verbose >= 2) printf("Creating /VS-DESCRIPTION...");
  457. #endif VERBOSE
  458.  
  459.     /* Create the VS-DESCRIPTION */
  460.     sprintf(vs_subdir,"%s/VS-DESCRIPTION",vs_root);
  461.     retval = mk_vdir(vs_subdir,MKVD_LPRIV);
  462.     if(retval && (retval != DIRSRV_ALREADY_EXISTS)) {
  463.         perrmesg("Error creating subdir: ", retval, NULL);
  464.         exit(1);
  465.     }
  466.     
  467.     /* create ROOT link */
  468.     sprintf(vs_subdir,"%s/VS-DESCRIPTION",vs_root);
  469.  
  470.     retval = rd_vdir(vs_root,0,dir,RVD_DFILE_ONLY);
  471.  
  472. #ifdef VERBOSE
  473.     if(verbose >= 2) printf("Done.\nAdding ROOT...");
  474. #endif VERBOSE
  475.  
  476.     retval = add_vlink(vs_subdir,"ROOT",dir->links,0);
  477.     if(retval) 
  478.         perrmesg("Error adding link to VS-DESCRIPTION: ", retval, NULL);
  479.     
  480. #ifdef VERBOSE
  481.     if(verbose >= 2) printf("Done.\nAdding HOME...");
  482. #endif VERBOSE
  483.  
  484.     vl = vlalloc();
  485.     
  486.     vl->name = stcopy("HOME");
  487.     stfree(vl->type); vl->type = stcopy("SYM-LINK");
  488.     stfree(vl->hosttype); vl->hosttype = stcopy("VIRTUAL-SYSTEM");
  489.     vl->filename = stcopy(home);
  490.  
  491.     /* Should LOCAL-VSLIST really be in prototype, or should it */
  492.     /* be in master.  I think in prototype, but should it       */
  493.     /* somehow encoded in HOME                                  */
  494.  
  495.     /* Clean up this code so we don't use dir->links */
  496.     sprintf(vs_temp,"/%s/VS-DESCRIPTION/LOCAL-VSLIST", P_PROTOTYPE_VS);
  497.     vllfree(dir->links);
  498.     dir->links = rd_slink(vs_temp);
  499.     if(!dir->links) {
  500.         fprintf(stderr,"Can't find prototype:/VS-DESCRIPTION/LOCAL-VSLIST\n");
  501.     }
  502.     /* hostname - need to figure it out in a better way */
  503.     sprintf(vsabsname,"%s/%s",dir->links->host,vsname);
  504.     vl->host = stcopy(vsabsname);
  505.  
  506.     retval = add_vlink(vs_subdir,"HOME",vl,0);
  507.     if(retval) 
  508.         perrmesg("Error adding VS-DESCRIPTION link: ", retval, NULL);
  509.     
  510. #ifdef VERBOSE
  511.     if(verbose >= 2) printf("Done.\n");
  512.  
  513.     if(verbose == 3) 
  514.         printf("\nAbout to add VS-DESCRIPTION to local VS list.\n[Type <CR> to continue]");
  515.  
  516.     if(verbose >= 4) {
  517.         printf("\nThe description of the new virtual system has been created, \n");
  518.         printf("but it has not yet been inserted into the global namespace.\n");
  519.         printf("We do this by adding the description to the local VS list.\n");
  520.         printf("This provides the VS with a default local name, and automatically\n");
  521.         printf("gives it a longer global name as well.  The global name is\n");
  522.         printf("The path from a well known point to to the local VS list, plus\n");
  523.         printf("the local name of the system.\n");
  524.  
  525.         printf("[Type <CR> to continue]");
  526.     }
  527.  
  528.     if(verbose >= 3) {
  529.         gets(cont);
  530.         printf("\n");
  531.     }
  532.  
  533.     if(verbose >= 2) 
  534.         printf("Adding to local VS list...");
  535. #endif VERBOSE
  536.  
  537.  
  538.     /* add a directory pointer to /VIRTUAL-SYSTEMS/#       */
  539.     /* This is done now through /prototype/VIRTUAL-SYSTEMS */
  540.     /* which is a pointer to the correct subdirectory      */
  541.     /* It might be better to start from # and traverse the */
  542.     /* whole path, but it would be slower.  Also should we */
  543.     /* start from prototype or master/VIRTUAL-SYSTEMS/#?   */
  544.  
  545.     /* create ROOT link */
  546.     sprintf(vs_subdir,"%s/VS-DESCRIPTION",vs_root);
  547.     retval = rd_vdir(vs_subdir,0,dir,RVD_DFILE_ONLY);
  548.     
  549.     if(retval == 0) {
  550.         sprintf(vs_temp,"/%s/VIRTUAL-SYSTEMS",P_PROTOTYPE_VS);
  551.         retval = add_vlink(vs_temp,vsname,dir->links,0); 
  552.     }
  553. #ifdef VERBOSE
  554.     if(verbose >= 2) printf("Done.\n");
  555. #endif VERBOSE
  556.  
  557.  
  558.     if(strcmp(vsdescfile,"-") == 0) goto nodesc;
  559.     
  560.     if((verbose >= 1) && (*vsdescfile == '\0')) {
  561.         printf("\nDo you want to create a virtual system description file?\n");
  562.         printf("The virtual system description file can be read by\n");
  563.         printf("vfsetup to find the description for this virtual\n");
  564.         printf("It is not absolutely necessary, because the\n");
  565.         printf("description can also be found by name.  If this is\n");
  566.         printf("your primary virtual system, then it is suggested that\n");
  567.         printf("you create a virtual system description file named\n");
  568.         printf("\"~/.virt-sys\".  This file is read when vfsetup is\n");
  569.         printf("called without arguments.\n\n");
  570.     }
  571.  
  572.     promptdescf:
  573.     if(*vsdescfile == '\0') {
  574.         printf("Create a virtual system description file (y/n)? ");
  575.         gets(vsdescfile);
  576.     }
  577.  
  578.     if((*vsdescfile == 'n') || (*vsdescfile == 'N')) goto nodesc;
  579.  
  580.     if((*vsdescfile != 'y') && (*vsdescfile != 'Y')) goto promptdescf;
  581.  
  582.     printf("Description file [~/.virt-sys]: ");
  583.     gets(vsdescfile);
  584.  
  585.     if(*vsdescfile == '\0') {
  586.         strcpy(vsdescfile,pget_hd());
  587.         strcat(vsdescfile,"/.virt-sys");
  588.     }
  589.     if((vsdesc = fopen(vsdescfile,"w")) == NULL) {
  590.         fprintf(stderr,"%s: Can't open system description file for write - %s\n",
  591.             progname,vsdescfile);
  592.         goto nodesc;
  593.         }
  594.         
  595.     /* Find VS-DESCRIPTION again */
  596.     sprintf(vs_subdir,"%s/VS-DESCRIPTION",vs_root);
  597.     retval = rd_vdir(vs_subdir,0,dir,RVD_DFILE_ONLY);
  598.  
  599.     if(!retval)
  600.         fprintf(vsdesc,"%s %s\n",dir->links->host,dir->links->filename);
  601.     else fprintf(stderr,"%s: Can't find VS-DESCRIPTION\n");
  602.     
  603.     fclose(vsdesc);
  604.  
  605.     nodesc:
  606.     exit(0);
  607.  
  608.     }
  609.